package com.marvels.approve.loan.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.PrintSetup;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.factory.annotation.Value;

import com.marvels.common.utils.MarvelsLogUtil;
import com.marvels.common.utils.ServerProperties;

/**
 * @author yuanjun
 * @date： 日期：2012-5-2 时间：下午4:56:13
 */
public class FileUtil {

	/**
	 * 获取文件夹  /yyyy/MM/dd/
	 */
	public static String getFileFolder(){
		Calendar calendar = Calendar.getInstance();
	    int day = calendar.get(Calendar.DATE);
	    int month = calendar.get(Calendar.MONTH) + 1;
	    int year = calendar.get(Calendar.YEAR);
		StringBuffer folder = new StringBuffer();
		folder.append("/")
			  .append(year)
			  .append("/")
			  .append(month<10?"0"+month:month)
			  .append("/")
			  .append(day)
			  .append("/");
		return folder.toString();
	}
	
	/**
	 * @Title:rename 
	 * @description:文件重命名
	 * @author yuanjun
	 * @param sourceFile：源文件对象
	 * @param destFileName：目标文件名字串
	 * @return void
	 * @throws
	 */
	public static void rename(File sourceFile, String destFileName) {
		String path = sourceFile.getParent();
		File destFile = new File(path, destFileName);
	
		try {			
			if (destFile.exists()) {
				destFile.delete();
			}
			sourceFile.renameTo(destFile);
		} catch (Exception e) {
			e.printStackTrace();
			MarvelsLogUtil.getInstance().error("",e);
		}
	}
	
	   /**  
     *  复制单个文件  
     *  @param  oldPath  String  原文件路径  如：c:/aa.txt  
     *  @param  newPath  String  复制后路径  如：f:/bb.txt  
     *  @return  boolean  
     */  
   public static  boolean  copyFile(String  oldPath,  String  newPath)  {  
	   InputStream  inStream = null;
	   FileOutputStream  fs = null;
       try  {  
           int  bytesum  =  0;
           int  byteread  =  0;
           File  oldfile  =  new  File(oldPath);  
           if  (oldfile.exists())  {  //文件存在时  
               inStream  =  new  FileInputStream(oldPath);  //读入原文件  
               fs  =  new  FileOutputStream(newPath);  
               byte[]  buffer  =  new  byte[1444];  

               while  (  (byteread  =  inStream.read(buffer))  !=  -1)  {  
                   bytesum  +=  byteread;  //字节数  文件大小  
                   fs.write(buffer,  0,  byteread);  
               }  
            }  
       }  
       catch  (Exception  e)  {  
           MarvelsLogUtil.getInstance().error("复制单个文件操作出错："+oldPath);	
           return false;
        }finally{
            try {
            	fs.flush();
            	fs.close();
				inStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}         	
        }
        return true;
   }  
   
   /**  
    *  移动单个文件到指定目录  
    *  @param  oldPath  String  如：c:/aa/
    *  @param  newPath  String  如：d:/bb/  
    */   
   public static void moveFile(String  oldPath,  String  newPath){
	   copyFile(oldPath,  newPath); 	   
       delFile(oldPath);
   }
   
   /**  
    *  删除文件
    *  @return  boolean  
    */  
  public static  boolean  delFile(String  filePath)  {  
      try  { 
   	   File file = new File(filePath);
   	   if(file.exists()){
   		   file.delete();
   	   }
       }  
      catch  (Exception  e)  {  
          MarvelsLogUtil.getInstance().error("删除文件操作出错："+filePath);
          return false;
       }  
      return true;
   }

	/**
	 * @Title:createFile 
	 * @description:新建文件或文件夹
	 * @author yuanjun
	 * @param filePath：目标文件名（完整路径）
	 * @throws IOException
	 * @return boolean
	 */
	public static boolean createFile(String filePath) throws IOException {
		if (filePath == null || "".equals(filePath.trim())) {
			throw new IOException("filePath is " + null + " or null String");
		}
		if (filePath.indexOf("/") != -1 && filePath.indexOf("\\") != -1) {
			throw new IOException("The filePath " + filePath + " is "
					+ " invalid");
		}
		File file = new File(filePath);
		boolean isDirectory = false;
		// 判断是否文件夹,若是文件夹则创建后返回
		if (filePath.lastIndexOf("/") == filePath.length() - 1
				|| filePath.lastIndexOf("\\") == filePath.length() - 1) {
			isDirectory = true;
		}
		if (isDirectory) {// 是文件夹
			if (file.isDirectory()) {// 若已存在,则无需创建,直接返回
				return true;
			} else {// 若不存在,则创建
				return createMkdirsOrFiles(filePath, 1);
			}
		} else {// 是文件
			if (file.isFile()) {// 若文件存在,则先删除,在创建,再返回
				boolean fd = file.delete();
				if (fd)
					return file.createNewFile();
				else
					return true;// 是否应该返回true,因为目标文件可能是删除不掉的原来的文件
			} else {// 若文件不存在,先创建,再返回
				return createMkdirsOrFiles(filePath, 2);
			}
		}
	}
	


	/**
	 * @Title:createMkdirsOrFiles 
	 * @description:创建文件夹或文件（目标文件或文件夹不存在）
	 * @author yuanjun
	 * @param filePath
	 * @param type：1-文件夹	2-文件
	 * @return boolean
	 * @throws IOException
	 */
	private static boolean createMkdirsOrFiles(String filePath, int type) throws IOException {
		// boolean res = false ;
		File file = new File(filePath);
		if (type == 1) {
			if (file.isDirectory())
				return true;
			file.mkdirs();
			return file.isDirectory();
		} else if (type == 2) {
			
			int index1 = file.getPath().indexOf(File.separator);
			if (index1 != -1) {
				int index2 = file.getPath().indexOf(File.separator, index1 + 1);
				if (index2 != -1) {
					int indexLast = file.getPath().lastIndexOf(File.separator);
					String dir = filePath.substring(0, indexLast + 1);
					File f = new File(dir);
					if (!f.isDirectory()) {
						f.mkdirs();
						boolean res = f.isDirectory();
						if (res) {
							file.createNewFile();
							return file.exists();
						} else {
							return false;
						}
					} else {
						file.createNewFile();
						return file.exists();
					}
				} else {
					file.createNewFile();
					return file.exists();
				}
			}else{
				throw new IOException("The filePath:" + filePath + " separator is " + " invalid");				
			}
		} else
			return false;
	}
	
	
	/**
	 * @Title:deleteFiles 
	 * @description:删除目标文件（目标可为文件夹，如包含多个文件一并删除）
	 * @author yuanjun
	 * @param file：文件对象
	 * @return boolean
	 */
	public static boolean deleteFiles(File file) {
		checkNull(file);
		boolean res = false;
		if (file == null)
			throw new RuntimeException();
		if (!file.exists()) {
			res = true;
			return res;
		}
		if (file.isFile()) {
			file.delete();
			res = !file.exists();
			return res;
		} else if (file.isDirectory() && file.listFiles().length == 0) {
			file.delete();
			res = !file.exists();
			return res;
		} else {
			File[] subFiles = file.listFiles();
			int len = subFiles.length;
			while (len > 0) {
				deleteFiles(subFiles[len - 1]);
				subFiles[len - 1].delete();
				len--;
			}
			file.delete();
			res = !file.exists();
			return res;
		}
	}
	
	
	/**
	 * @Title:checkNull 
	 * @description:检测对象是否为空
	 * @author yuanjun
	 * @param args
	 */
	static void checkNull(Object args){
		if(args == null )
			throw new NullPointerException("args is null");
	}
	
	
	/**
	 * 从excel文件中读取数据
	 * @param is
	 * @return
	 */
	public static List<List<List<String>>> readExcelFile(InputStream is){
		List<List<List<String>>> sheetList = new ArrayList<List<List<String>>>();
		try { 
			Workbook wb =  WorkbookFactory.create(is);
			
			Sheet sheet = null;   
			Row row = null; 
			List<List<String>> sheetDataList = null;
			List<String> rowDataList = null;
			Map map = new HashMap();//用来判断是否空行
			/*
			 * 取得sheet，如果你的workbook里有多个sheet 可以利用 wb.getSheets()方法来得到所有的。
			 * getSheets() 方法返回 Sheet[] 数组 然后利用数组来操作。就是多次循环的事。
			 */
			for (int i = 0; i < wb.getNumberOfSheets(); i++) {
				sheet = wb.getSheetAt(i);
				sheetDataList = new ArrayList<List<String>>();
				//System.out.println("rowNum:"+sheet.getLastRowNum());
				for (int j = 0; j <= sheet.getLastRowNum(); j++) {
					row = sheet.getRow(j);  
					if(row!=null){
						//System.out.println("************");
						
						rowDataList = new ArrayList<String>();
						//System.out.println("CellNum:"+row.getLastCellNum());
						map.clear();
						for (int k = 0; k <= row.getLastCellNum(); k++) {
							Cell cell = row.getCell(k);
							
							if(cell==null){
								rowDataList.add(null);
								continue;
							}
							int type = cell.getCellType();
						
							String cellValue = null;
							
							if(type==Cell.CELL_TYPE_NUMERIC){
								cellValue = String.valueOf(cell.getNumericCellValue());
								System.out.println(new BigDecimal(cell.getNumericCellValue()).toBigInteger());
								//对于数值型科学技术法的数值的处理
								BigDecimal result = null;
								if(cellValue!=null && cellValue.indexOf('E')>-1){
									String[] parts = cellValue.split("E");
									try{
										result = new BigDecimal(parts[0]).multiply(BigDecimal.TEN.pow(Integer.valueOf(parts[1])));
									}catch(Exception e){
										e.printStackTrace();
									}
								}
								if(result!=null){
									cellValue=result.toString();
								}
							}else if(type==Cell.CELL_TYPE_STRING){
								
								cellValue = cell.getRichStringCellValue().getString();
								//System.out.println("????????"+cellValue);
							}else if(type==Cell.CELL_TYPE_BOOLEAN){
								cellValue = String.valueOf(cell.getBooleanCellValue());
							}else if(type==Cell.CELL_TYPE_ERROR){
								cellValue = String.valueOf(cell.getErrorCellValue());
							}else if(type==Cell.CELL_TYPE_FORMULA){
								//cellValue = cell.getCellFormula();
								System.out.println(new BigDecimal(cell.getNumericCellValue()).intValue());
								cellValue = String.valueOf(cell.getNumericCellValue());
							}
							if(cell!=null&&!"".equals(cell.toString().trim())){
								map.put(cellValue, null);
							}
							rowDataList.add(cellValue);
						}
						if(map.isEmpty()){
							continue;
						}
						sheetDataList.add(rowDataList);
					}
				}
				sheetList.add(sheetDataList);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("读取EXCEL文档出错!", e);
		} 
		//System.out.println(sheetList);
		return sheetList;
	}

	/**
	 * 读取EXCEL文档内容
	 * @param filePath 文件路径
	 * @param fileName 文件名
	 * @return
	 */
	public static List readExcelFile(String filePath,String fileName) {
		InputStream is = null;
		try{
			is = new FileInputStream(filePath + fileName);
		}catch(Exception e){
			e.printStackTrace();
		}
		return readExcelFile(is);
	}
	/**
	 * 读取EXCEL文档内容
	 * @param file
	 * @return
	 */
	public static List readExcelFile(File file){
		return readExcelFile(file);
	}
	/*public static void main(String[] args){
		String dateStr = "23";
		//System.out.println("xxx"+DateUtil.parseDate(dateStr)+"xx");
		//System.out.println(readExcelFile("e:\\","test2.xlsx"));
		System.out.println(readCSVFile(new File("e:\\testx.csv")));
		//System.out.println(formatExcelInt("40949.22"));
	}*/
	/**
	 * 上传临时文件路径
	 * @return
	 */
	public static String getRepositoryPath() {

	      String tempDir = null;
	      //		First, look for an explicitly defined temp dir.

	      //tempDir = Global.getString(Constants.UPLOAD_TEMPDIR);

	      // If none, look for a container specified temp dir.
	      if (tempDir == null || tempDir.length() == 0) {
	          // If none, pick up the system temp dir.
	          if (tempDir == null || tempDir.length() == 0) {
	              tempDir = System.getProperty("java.io.tmpdir");
	          }
	      }
	      return tempDir;

	}
	/**
	 * 从excel读取的日期类型为从1900年1月1日到该日的天数，为double类型，此函数做转换
	 * @param excelDate
	 * @return
	 */
	public static Date formatExcelDate(String excelDate){
		Date date = HSSFDateUtil.getJavaDate( new Double( excelDate ));
		return date;
	}
	/**
	 * 从excel读取的int类型都为都为double类型，此函数做转换
	 * @param excelInt
	 * @return
	 */
	public static String formatExcelInt(String excelInt){
		BigDecimal i = null;
		try{
			i = new BigDecimal(excelInt);
		}catch(Exception e){
			//不抛异常
		}
		if(i==null){
			return null;
		}
		return i.toBigInteger().toString();
	}
	/**
	 * 读取CSV文档内容
	 * 注：读取CSV，为了业务类兼容excel方式，因此依然返回的是sheetList（多个sheet列表）
	 * @param File 文件路径
	 * @return
	 */
	/*public static List<List<List<String>>> readCSVFile(File file) {
		String fileContent = null;
		BufferedReader fr = null;
		List<List<List<String>>> sheetList = new ArrayList<List<List<String>>>();
		List<List<String>> sheetDataList = new ArrayList<List<String>>();
		List<String> rowDataList = null;
		String[] columns = null;
		try {
			StringBuffer sb = new StringBuffer();
			UploadHandler handler = new UploadHandler();
			if (file!=null) {
				//fr = new BufferedReader(new FileReader(file) , handler.getEncode(file));
				fr = new BufferedReader(new InputStreamReader(new FileInputStream(file) , handler.getEncode(file)));
				String lineContent = fr.readLine();
				while (lineContent != null) {
					columns = lineContent.split(",");
					//没有采用Arrays.asList方法，获取的list无法add？？？UnsupportOperationException
					rowDataList = new ArrayList<String>();
					for(int i=0;i<columns.length;i++){
						rowDataList.add(columns[i]);
					}
					if(rowDataList!=null&&rowDataList.size()>0)
						sheetDataList.add(rowDataList);
					//sb.append(lineContent);
					lineContent = fr.readLine();
				}
				fr.close();
			}
			//fileContent = sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("读取文本文档出错!", e);
		} finally {
			try {
				if (fr != null)
					fr.close();
			} catch (Exception e) {
				e.printStackTrace();
				throw new RuntimeException("读取文本文档出错!", e);
			}
		}
		sheetList.add(sheetDataList);
		return sheetList;
	} */
	/**
	 * 把数据生成一个excel文件
	 * @param dataList
	 * @return
	 */
	public static Workbook writeExcelFile(List<List<String>> dataList){
		Workbook workbook = null;
		workbook = new HSSFWorkbook();//new XSSFWorkbook();
		Map<String, CellStyle> styles = createStyles(workbook);
		Sheet sheet = workbook.createSheet("Sheet 1");
		PrintSetup printSetup = sheet.getPrintSetup();
		printSetup.setLandscape(true);
		sheet.setFitToPage(true);
		sheet.setHorizontallyCenter(true);
		
		List<String> rowList = null;
		Row row = null;
		Cell cell = null;
		for(int i=0;i<dataList.size();i++){
			rowList = dataList.get(i);
			row = sheet.createRow(i);
			for(int j=0;j<rowList.size();j++){
				cell = row.createCell(j);
				cell.setCellStyle(styles.get("cell"));
				cell.setCellValue(rowList.get(j));
			}
		}
	    return workbook;

	}
	private static Map<String, CellStyle> createStyles(Workbook wb){
        Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
        CellStyle style;
        Font titleFont = wb.createFont();
        titleFont.setFontHeightInPoints((short)18);
        titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
        style = wb.createCellStyle();
        style.setAlignment(CellStyle.ALIGN_CENTER);
        style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        style.setFont(titleFont);
        styles.put("title", style);

        Font monthFont = wb.createFont();
        monthFont.setFontHeightInPoints((short)11);
        monthFont.setColor(IndexedColors.WHITE.getIndex());
        style = wb.createCellStyle();
        style.setAlignment(CellStyle.ALIGN_CENTER);
        style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
        style.setFillPattern(CellStyle.SOLID_FOREGROUND);
        style.setFont(monthFont);
        style.setWrapText(true);
        styles.put("header", style);

        style = wb.createCellStyle();
        style.setAlignment(CellStyle.ALIGN_CENTER);
        style.setWrapText(true);
        style.setBorderRight(CellStyle.BORDER_THIN);
        style.setRightBorderColor(IndexedColors.BLACK.getIndex());
        style.setBorderLeft(CellStyle.BORDER_THIN);
        style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
        style.setBorderTop(CellStyle.BORDER_THIN);
        style.setTopBorderColor(IndexedColors.BLACK.getIndex());
        style.setBorderBottom(CellStyle.BORDER_THIN);
        style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
        styles.put("cell", style);

        style = wb.createCellStyle();
        style.setAlignment(CellStyle.ALIGN_CENTER);
        style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        style.setFillPattern(CellStyle.SOLID_FOREGROUND);
        style.setDataFormat(wb.createDataFormat().getFormat("0.00"));
        styles.put("formula", style);

        style = wb.createCellStyle();
        style.setAlignment(CellStyle.ALIGN_CENTER);
        style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
        style.setFillForegroundColor(IndexedColors.GREY_40_PERCENT.getIndex());
        style.setFillPattern(CellStyle.SOLID_FOREGROUND);
        style.setDataFormat(wb.createDataFormat().getFormat("0.00"));
        styles.put("formula_2", style);

        return styles;
    }

	public static String fileNameSuffix() {
		return Now("yyyyMMddHHmmssSSS");
	}
	public static String Now(String strFormat) {
		DateFormat df = new java.text.SimpleDateFormat(strFormat);
		java.util.Date d = new java.util.Date();
		return df.format(d);
	}
	
   
}
